#!/usr/bin/env python
# encoding: utf-8
"""
main.py

Created by Daniel Greenfeld on 2008-03-18.
Copyright (c) 2008 __MyCompanyName__. All rights reserved.
"""
import wx
import wx.richtext as rt
from sqlalchemy.orm import sessionmaker  
from sqlalchemy.orm import eagerload
import model
from model import Book, Chapter, Scene
ID_BUTTON = 100

class MainWindow(wx.Frame):
    """wxProject MainFrame."""
    def __init__(self, parent, title):
        """Create the wxProject MainFrame."""
        wx.Frame.__init__(self, parent, title=title, size=(500, 500),
                          style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
        
        # get database session
        Session = sessionmaker(bind=engine,autoflush=True,transactional=True) 
        self.session = Session()
        
        # create status bar
        self.CreateStatusBar()
        self.SetStatusText('genWriter')    
        
        self.MakeMenuBar() 
        
        # do the bottom bar
        """winids = []        
        bottomwin = wx.SashLayoutWindow(self,-1,wx.DefaultPosition, (200,30),
                            wx.NO_BORDER|wx.SW_3D)
        bottomwin.SetDefaultSize((100,30))
        bottomwin.SetOrientation(wx.LAYOUT_HORIZONTAL)
        bottomwin.SetAlignment(wx.LAYOUT_BOTTOM)
        bottomwin.SetSashVisible(wx.SASH_TOP, True)
        self.bottomwin = bottomwin
        winids.append(bottomwin.GetId())
        """
        
        # Create the splitter window.
        self.splitter = wx.SplitterWindow(self, style=wx.NO_3D|wx.SP_3D)
        self.splitter.SetMinimumPaneSize(1)        
        
        # tree on left
        self.tree = wx.TreeCtrl(self.splitter, style=wx.TR_DEFAULT_STYLE)
        self.root = self.tree.AddRoot('Books')
        self.ids = {}
        for book in self.session.query(Book):
            child_book = self.tree.AppendItem(self.root,book.name)
            self.ids[child_book] = book
            for chapter in self.session.query(Chapter).filter_by(id=book.id):
                child_chapter = self.tree.AppendItem(child_book,chapter.name)
                self.ids[child_chapter] = chapter
                for scene in self.session.query(Scene).filter_by(id=chapter.id):
                    child_scene = self.tree.AppendItem(child_chapter,scene.name)
                    self.ids[child_scene] = scene
        self.tree.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.OnExpandItem)
        self.tree.Bind(wx.EVT_TREE_ITEM_COLLAPSING, self.OnCollapseItem)
        self.tree.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnActivatedItem)
        self.tree.__collapsing = False
        
        
        # rte on right
        self.rtc = rt.RichTextCtrl(self.splitter,style=wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER)
                
        
        # Install the tree and the editor.
        self.splitter.SplitVertically(self.tree, self.rtc)
        self.splitter.SetSashPosition(180, True)
        
        # add metadata
        #self.SetMetaData()
     
        # Some global state variables.
        self.projectdirty = False
        self.root = None
        self.close = False
        
        self.Show(True)  
        
    def SetMetaData(self):
        self.sizer2 = wx.BoxSizer(wx.HORIZONTAL)
        
        button1 = wx.Button(self, ID_BUTTON + 1, "F3 View")
        button2 = wx.Button(self, ID_BUTTON + 2, "F4 Edit")
        button3 = wx.Button(self, ID_BUTTON + 3, "F5 Copy")
        button4 = wx.Button(self, ID_BUTTON + 4, "F6 Move")
        button5 = wx.Button(self, ID_BUTTON + 5, "F7 Mkdir")
        button6 = wx.Button(self, ID_BUTTON + 6, "F8 Delete")
        button7 = wx.Button(self, ID_BUTTON + 7, "F9 Rename")

        self.sizer2.Add(button1, 1, wx.EXPAND)
        self.sizer2.Add(button2, 1, wx.EXPAND)
        self.sizer2.Add(button3, 1, wx.EXPAND)
        self.sizer2.Add(button4, 1, wx.EXPAND)
        self.sizer2.Add(button5, 1, wx.EXPAND)
        self.sizer2.Add(button6, 1, wx.EXPAND)
        self.sizer2.Add(button7, 1, wx.EXPAND)


        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.splitter,1,wx.EXPAND)
        self.sizer.Add(self.sizer2,0,wx.EXPAND)
        self.SetSizer(self.sizer)

        size = wx.DisplaySize()
        self.SetSize(size)                  
        
    def MakeMenuBar(self):
        def doBind(item, handler, updateUI=None):
            self.Bind(wx.EVT_MENU, handler, item)
            if updateUI is not None:
                self.Bind(wx.EVT_UPDATE_UI, updateUI, item)

        # set up filemenu
        filemenu = wx.Menu()
        doBind(filemenu.Append(-1, "&Save\tCtrl+S", "Save"),
                self.OnFileSave )   
        doBind(filemenu.Append(-1, "Save As", "Save As"),
                self.OnFileSaveAs )   
        filemenu.AppendSeparator()
        doBind(filemenu.Append(-1, "&About\tCtrl+A", "Information about this program"),
                self.OnAbout )        
        doBind(filemenu.Append(-1, "E&xit\tCtrl+Q", "Quit this program"),
                self.OnExit )         

        # set up editmenu
        editmenu = wx.Menu()
        doBind(editmenu.Append(-1, "&Bold\tCtrl+B"),
                self.OnBold )        

        # set up formatmenu
        formatmenu = wx.Menu()
        doBind(formatmenu.Append(-1,'Single spacing','Single spacing'),self.OnLineSpacingSingle)
        doBind(formatmenu.Append(-1,'Half spacing','Half spacing'),self.OnLineSpacingHalf)
        doBind(formatmenu.Append(-1,'Double spacing','Double spacing'),self.OnLineSpacingDouble)


        # create the menubar
        menubar = wx.MenuBar()
        menubar.Append(filemenu,'&File')
        menubar.Append(editmenu,'&Edit')        
        menubar.Append(formatmenu,'Format')        
        self.SetMenuBar(menubar)   
        
    def OnActivatedItem(self,event,item=None):
        self.rtc.Clear()
        if event:
            item = event.GetItem()
        self.activeitem = item
        if item != self.root:
            #self.rtc.WriteText(self.tree.GetItemText(item))
            #self.rtc.WriteText(': ')
            # load the current selected file 
            for key,value in self.ids.items(): 
                if item == key:
                    self.rtc.WriteText(value.description)
            self.rtc.WriteText(str(self.OnFileSaveAs.__doc__))
            self.rtc.SetFocus()
        else:
            self.editor.Clear()

                
    def OnExpandItem(self, event):
        # For expansion
        item = event.GetItem()


    def OnCollapseItem(self, event):
        # Be prepared, self.CollapseAndReset below may cause
        # another wx.EVT_TREE_ITEM_COLLAPSING event being triggered.
        if self.__collapsing:
            event.Veto()
        else:
            self.tree.__collapsing = True
            item = event.GetItem()
            self.CollapseAndReset(item)
            self.SetItemHasChildren(item)
            self.__collapsing = False             

    # event handlers
    def OnLineSpacingSingle(self, evt): 
        attr = rt.TextAttrEx()
        attr.SetFlags(rt.TEXT_ATTR_LINE_SPACING)
        ip = self.rtc.GetInsertionPoint()
        if self.rtc.GetStyle(ip, attr):
            r = rt.RichTextRange(ip, ip)
            if self.rtc.HasSelection():
                r = self.rtc.GetSelectionRange()

            attr.SetFlags(rt.TEXT_ATTR_LINE_SPACING)
            attr.SetLineSpacing(10)
            self.rtc.SetStyle(r, attr)


    def OnLineSpacingHalf(self, evt):
        attr = rt.TextAttrEx()
        attr.SetFlags(rt.TEXT_ATTR_LINE_SPACING)
        ip = self.rtc.GetInsertionPoint()
        if self.rtc.GetStyle(ip, attr):
            r = rt.RichTextRange(ip, ip)
            if self.rtc.HasSelection():
                r = self.rtc.GetSelectionRange()

            attr.SetFlags(rt.TEXT_ATTR_LINE_SPACING)
            attr.SetLineSpacing(15)
            self.rtc.SetStyle(r, attr)


    def OnLineSpacingDouble(self, evt):
        attr = rt.TextAttrEx()
        attr.SetFlags(rt.TEXT_ATTR_LINE_SPACING)
        ip = self.rtc.GetInsertionPoint()
        if self.rtc.GetStyle(ip, attr):
            r = rt.RichTextRange(ip, ip)
            if self.rtc.HasSelection():
                r = self.rtc.GetSelectionRange()

            attr.SetFlags(rt.TEXT_ATTR_LINE_SPACING)
            attr.SetLineSpacing(20)
            self.rtc.SetStyle(r, attr)

    def OnBold(self, event):
        self.rtc.ApplyBoldToSelection()


    def OnAbout(self,event):
        d = wx.MessageDialog(self,
                                'genWriter is written \n in wxPython','About Sample Editor', wx.OK)
        d.ShowModal() # shows it
        d.Destroy() # destroys it when finished

    def OnExit(self,event):
        self.Close(True) # close the frame

    def OnFileSave(self, evt):
        if not self.rtc.GetFilename():
            self.OnFileSaveAs(evt)
            return
        self.rtc.SaveFile()


    def OnFileSaveAs(self, evt):
        wildcard, types = rt.RichTextBuffer.GetExtWildcard(save=True)

        dlg = wx.FileDialog(self, "Choose a filename",
                            wildcard=wildcard,
                            style=wx.SAVE)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            if path:
                fileType = types[dlg.GetFilterIndex()]
                ext = rt.RichTextBuffer.FindHandlerByType(fileType).GetExtension()
                if not path.endswith(ext):
                    path += '.' + ext
                self.rtc.SaveFile(path, fileType)
        dlg.Destroy()
                


class App(wx.App):
    """wxProject Application."""
    def OnInit(self):
        """Create the wxProject Application."""
        frame = MainWindow(None, 'genWriter')
        return True


if __name__ == '__main__':
    from model import create_database    
    
    engine = create_database()    
    Session = sessionmaker(bind=engine,autoflush=True,transactional=True) 
    session = Session()
    book1 = Book('Fun with pycon 2008','My first Pycon')
    book1.chapters.append(Chapter('Introduction','slaggo'))
    session.save(book1)
    session.save(Book('genWriter',"A writer's best friend"))    
    session.save(Book('Enterprise Python',"Just when you thought Python was ok..."))        
    session.commit()
    app = App(0)
    app.MainLoop()
    